package br.com.toscano.contpedido.business;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import javax.inject.Inject;

import br.com.toscano.contpedido.domain.Licenca;
import br.com.toscano.contpedido.exception.ValidadorLicencaException;
import br.com.toscano.contpedido.persistence.LicencaDAO;
import br.com.toscano.contpedido.util.HardUtils;
import br.com.toscano.contpedido.view.converter.DateConverter;
import br.gov.frameworkdemoiselle.lifecycle.Startup;
import br.gov.frameworkdemoiselle.stereotype.BusinessController;
import br.gov.frameworkdemoiselle.template.DelegateCrud;
import br.gov.frameworkdemoiselle.transaction.Transactional;
import br.gov.frameworkdemoiselle.util.ResourceBundle;

@BusinessController
public class LicencaBC extends DelegateCrud<Licenca, Long, LicencaDAO> {

	private final long serialVersionUID = 1324L;

	private static String codigoValidadeLicenca; 
	
	public String SEPARADOR = "@##@";

	public static String ERRO_00 = "ERRO_00";
	public static String MENSAGEM_00 = "Licença Invalida";

	public static String ERRO_01 = "ERRO_01";
	public static String MENSAGEM_01 = "Não foi encontrdo o arquvio de versão do sistema!";

	public static String ERRO_02 = "ERRO_02";
	public static String MENSAGEM_02 = "A versão da licença não é para a versão do sistema!";

	public static String ERRO_03 = "ERRO_03";
	public static String MENSAGEM_03 = "Sistema Expirou!";

	public static String ERRO_04 = "ERRO_04";
	public static String MENSAGEM_04 = "Sistema sem Licença!";

	public static String ERRO_05 = "ERRO_05";
	public static String MENSAGEM_05 = "A data de uso da lincença não é para hoje. \n A licença tem que ser gerada hoje!";

	public static String ERRO_06 = "ERRO_06";
	public static String MENSAGEM_06 = "Licença Gerada não é para essa Máquina!";

	public static String ERRO_07 = "ERRO_07";
	public static String MENSAGEM_07 = "Solicitação da Licença Invalida!";

	public static String ERRO_08 = "ERRO_08";
	public static String MENSAGEM_08 = "Data de solicitação não é de hoje.\nSolicitação tem que ser gerada hoje!";

	public static String ERRO_09 = "ERRO_09";
	public static String MENSAGEM_09 = "Cliente não cadastrada. \n Favor entrar em contato com o suporte!";

	public static String ERRO_10 = "ERRO_10";
	public static String MENSAGEM_10 = "Cliente desativado e renovação não autorizada. \n Favor entrar em contato com o suporte!";

	public static String ERRO_11 = "ERRO_11";
	public static String MENSAGEM_11 = "Cliente já cadastrado com o código dessa solicitação. \n Favor entrar em contato com o suporte!";

	public static String ERRO_12 = "ERRO_12";
	public static String MENSAGEM_12 = "A licneca gerada nao para esse produto. \n Favor entrar em contato com o suporte!";

	@Inject
	private ResourceBundle bundle;

	public static String getCodigoValidadeLicenca() {
		return codigoValidadeLicenca;
	}

	@Startup
	@Transactional
	public void load() {
		validarLicenca();
	}
	
	public void validarLicenca() {
		Licenca licenca = null;
		List<Licenca> listaLicenca = findAll();
		for (Licenca l : listaLicenca) {
			if (licenca == null || l.getId() > licenca.getId()) {
				licenca = l;
			}
		}
		
		validarLicenca(licenca);
		
	}

	public String insert(String licencaString) {
		try {
			Licenca licenca = licencaStringToLicenca(licencaString);

			licenca = this.getDelegate().insert(licenca);

			validarLicenca(licenca);
			
			return this.getCodigoValidadeLicenca();

		} catch (Throwable e) {
			throw new IllegalArgumentException(e);
		}
	}
	
	@Override
	public Licenca insert(Licenca bean) {
		throw new IllegalArgumentException("Não pode atualizar uma licenca");
	}
	
	public String gerarSolicitacaoLicenca() throws Throwable{
		String produto = bundle.getString("produto");
		String versao = bundle.getString("versao");
		Long dataSolicitacao = new Date().getTime();
		String mac = HardUtils.getId(produto);

		return produto + SEPARADOR + versao + SEPARADOR + dataSolicitacao+ SEPARADOR + mac;
	}
	
	public void autenticarAutomaticamente() {
		if (getCodigoValidadeLicenca() == null || !"".equals(getCodigoValidadeLicenca())) {

			String ipPrimario=bundle.getString("ipPrimario");
			String portaPrimaria=bundle.getString("portaPrimaria");
			String ipSecundario=bundle.getString("ipSecundario");
			String portaSecundario=bundle.getString("portaSecundario");
			
			String servico="";
			String servicoSecundario="";

			try {
				servico =bundle.getString("servico");
			} catch (Exception e) {
				// TODO: handle exception
			}
			try {
				servicoSecundario=bundle.getString("servicoSecundario");
			} catch (Exception e) {
				// TODO: handle exception
			}

			Licenca ultimaLicenca = retornarUltimaLicenca();

			if (ultimaLicenca != null) {
				ipPrimario = ultimaLicenca.getServico();
				portaPrimaria = ultimaLicenca.getPorta();
				ipSecundario = ultimaLicenca.getServicoSecundario();
				portaSecundario = ultimaLicenca.getPortaSecundario();
				if (ultimaLicenca.getServico() != null && !"".equals(ultimaLicenca.getServico())) { 
					servico = ultimaLicenca.getServico();
				}
				if (ultimaLicenca.getServicoSecundario() != null && !"".equals(ultimaLicenca.getServicoSecundario())) { 
					servicoSecundario = ultimaLicenca.getServicoSecundario();
				}
			}

			try {
				String licencaServidorOnLine = pegarLicencaDoServidor(servico, ipPrimario,portaPrimaria);
				if (licencaServidorOnLine != null && !"".equals(licencaServidorOnLine)) {
					String mensagemLicenaOnLine = insert(licencaServidorOnLine);
				} else if (licencaServidorOnLine == null || "".equals(licencaServidorOnLine)) {
					licencaServidorOnLine = pegarLicencaDoServidor(servicoSecundario,ipSecundario,portaSecundario);
					if (licencaServidorOnLine != null && !"".equals(licencaServidorOnLine)) {
						String mensagemLicenaOnLine = insert(licencaServidorOnLine);
					}	
				}
			} catch (ValidadorLicencaException e) {
//				usuario.setCodigoErroLicenca(e.getErro());
			}
		}
	}

	private Licenca retornarUltimaLicenca() {
		Licenca ultimaLicenca = null;
		List<Licenca> lista = this.findAll();
		if(lista != null){
			for (Licenca licencaCadastrada : lista) {
				if (ultimaLicenca == null || ultimaLicenca.getDataGeracao().longValue() < licencaCadastrada.getDataGeracao().longValue()){
					ultimaLicenca = licencaCadastrada;
				}
			}
		}
		return ultimaLicenca;
	}
	
	private String pegarLicencaDoServidor(String servico, String ip, String porta) throws ValidadorLicencaException {
		String retorno = null;
		
			String solicitacao = "";
			try {
				solicitacao = gerarSolicitacaoLicenca();
			} catch (Throwable e) {
				return retorno;
			}
 
			try {
				URL urlCon = new URL("http://" + ip + ":" + porta + "/"
						+ servico
						+ "/AutenticadorLicencaOnLine.servlet?solicitacao="+solicitacao);
				URLConnection huc1 = urlCon.openConnection();
	
				huc1.setAllowUserInteraction(true);
				huc1.setDoOutput(true);
	
				ObjectOutputStream output = new ObjectOutputStream(huc1.getOutputStream());
				output.writeObject(solicitacao);
				ObjectInputStream input = new ObjectInputStream(huc1.getInputStream());
				Object obj = input.readObject();
				if (obj instanceof String) {
					//tem licenca
					retorno = obj.toString();
				} else  if (obj instanceof ValidadorLicencaException){
					((Exception)obj).printStackTrace();
					throw (ValidadorLicencaException)obj;
				} else  if (obj instanceof Exception){
					((Exception)obj).printStackTrace();
					throw new ValidadorLicencaException(((Exception)obj).getMessage());
				}
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		return retorno;
	}
	
	@Override
	public Licenca update(Licenca ultimaLicenca) {
		throw new IllegalArgumentException("Não pode atualizar uma licenca");
	}

	private void validarLicenca(Licenca ultimaLicenca) {
		String retorno = "";
		try {
			String versao = bundle.getString("versao");
			
			
			if (versao == null || "".equals(versao) || "0".equals(versao)) {
				retorno = ERRO_01;
			} else {
				if (ultimaLicenca == null) {
					retorno = ERRO_04;
				} else {
					if (!versao.equals(ultimaLicenca.getVersao())) {
						retorno = ERRO_02;
					} else if (new Date().getTime() > ultimaLicenca
							.getDataVencimento().longValue()) {
						retorno = ERRO_03;
					}
				}
			}
			
			codigoValidadeLicenca = retorno;
			
		} catch (Exception e) {
			codigoValidadeLicenca = null;
		}
	}

	public String getDescricaoErro(String erro) {
		String descricaoErro = "";

		if (ERRO_00.equals(erro) ) return  ERRO_00 + " - " + MENSAGEM_00;
		if (ERRO_01.equals(erro) ) return  ERRO_01 + " - " + MENSAGEM_01;
		if (ERRO_02.equals(erro) ) return  ERRO_02 + " - " + MENSAGEM_02;
		if (ERRO_03.equals(erro) ) return  ERRO_03 + " - " + MENSAGEM_03;
		if (ERRO_04.equals(erro) ) return  ERRO_04 + " - " + MENSAGEM_04;
		if (ERRO_05.equals(erro) ) return  ERRO_05 + " - " + MENSAGEM_05;
		if (ERRO_06.equals(erro) ) return  ERRO_06 + " - " + MENSAGEM_06;
		if (ERRO_07.equals(erro) ) return  ERRO_07 + " - " + MENSAGEM_07;
		if (ERRO_08.equals(erro) ) return  ERRO_08 + " - " + MENSAGEM_08;
		if (ERRO_09.equals(erro) ) return  ERRO_09 + " - " + MENSAGEM_09;
		if (ERRO_10.equals(erro) ) return  ERRO_10 + " - " + MENSAGEM_10;
		if (ERRO_11.equals(erro) ) return  ERRO_11 + " - " + MENSAGEM_11;
		if (ERRO_12.equals(erro) ) return  ERRO_12 + " - " + MENSAGEM_12;
		
		return descricaoErro;
	}

	public Licenca licencaStringToLicenca(String obj) throws Throwable{

		String produto = "";
		String dadaUso = "";
		String mac = "";
		String dataGeracao = "";
		String dataVencimento = "";
		String servico = "";
		String servicoSecundario = "";
		String versao = "";
		String porta = "";
		String portaSecundario = "";

		try {
			StringTokenizer st = new StringTokenizer((obj + "").trim(),SEPARADOR);
			produto = st.nextToken();
			dadaUso = st.nextToken();
			mac = st.nextToken();
			dataGeracao = st.nextToken();
			dataVencimento = st.nextToken();
			servico = st.nextToken();
			servicoSecundario = st.nextToken();
			versao = st.nextToken();
			porta = st.nextToken();
			portaSecundario = st.nextToken();
			if (st.hasMoreTokens()) {
				servico = st.nextToken();
			}
			if (st.hasMoreTokens()) {
				servicoSecundario = st.nextToken();
			}
		} catch (Exception e) {
			throw new Exception(ERRO_00);
			//"LicenÃ§a InvÃ¡lida!"
		}
		
		String produtoSGPM = bundle.getString("produto");

		if (!produto.equals(produtoSGPM)) {
			throw new Exception(ERRO_12);
		}

		Date data = new Date(new Long(dadaUso));
		Date dataHoje = new Date();
		if (!DateConverter.getDate(data).equals(DateConverter.getDate(dataHoje))) {
			throw new Exception(ERRO_05);
		} 
		
		String macMaquina = HardUtils.getId(produto);
		
		if (!macMaquina.equals(mac)) {
			throw new Exception(ERRO_06);
		}

		Licenca licenca = new Licenca();
		licenca.setLicenca(obj);
		licenca.setDataGeracao(new Long(dataGeracao));
		licenca.setDataVencimento(new Long(dataVencimento));
		licenca.setServico(servico);
		licenca.setServicoSecundario(servicoSecundario);
		licenca.setVersao(versao);
		licenca.setPorta(porta);
		licenca.setServico(servico);
		licenca.setServicoSecundario(servicoSecundario);
		licenca.setPortaSecundario(portaSecundario);
		licenca.setDataGravacao(new Date().getTime());

		return licenca;
	}
	
	@Override
	@Transactional
	public void delete(Long id) {
		this.getDelegate().delete(id);
	}

	@Override
	@Transactional
	public void delete(List<Long> ids) {
		// TODO Auto-generated method stub
		for (Long id : ids) {
			this.delete(id);
		}
	}

}